package cn.edu.xmu.orderpayment.order.controller;

import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.orderpayment.order.model.vo.NewAfterSaleOrderVo;
import cn.edu.xmu.orderpayment.order.model.vo.NewOrderVo;
import cn.edu.xmu.orderpayment.order.model.bo.Order;
import cn.edu.xmu.orderpayment.order.model.vo.OrderModifyVo;
import cn.edu.xmu.orderpayment.order.model.vo.ShipmentVo;
import cn.edu.xmu.orderpayment.order.service.OrderService;
import cn.edu.xmu.privilegegateway.annotation.aop.Audit;
import cn.edu.xmu.privilegegateway.annotation.aop.LoginName;
import cn.edu.xmu.privilegegateway.annotation.aop.LoginUser;
import cn.edu.xmu.privilegegateway.annotation.util.InternalReturnObject;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import static cn.edu.xmu.oomall.core.util.Common.*;
import static cn.edu.xmu.privilegegateway.annotation.util.Common.cloneVo;

import javax.servlet.http.HttpServletResponse;
import java.time.ZonedDateTime;

/**
 * @author YuJie
 * @date 2021-12-02
 */
@RestController
@RefreshScope
@RequestMapping(value = "/", produces = "application/json;charset=UTF-8")
public class OrderController {

    private final Logger logger = LoggerFactory.getLogger(OrderController.class);

    @Autowired
    private HttpServletResponse httpServletResponse;

    @Autowired
    private OrderService orderService;

    @ApiOperation(value = "获取订单所有状态")
    @GetMapping("orders/states")
    public Object getAllState() {

        ReturnObject res = orderService.getAllState();
        return decorateReturnObject(res);
    }


    /**
     * 通过父订单id获得所有子订单详细信息，类型为List
     * @param pid
     * @return
     */
    @GetMapping("internal/childorders/{pid}")
    public InternalReturnObject getOrderByPid(@PathVariable Long pid){
        if(pid<=0){
            return new InternalReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST.getCode(),ReturnNo.RESOURCE_ID_NOTEXIST.getMessage());
        }
        ReturnObject res = orderService.getOrderByPid(pid);

        InternalReturnObject ret = new InternalReturnObject();
        if(res.getData()!=null)
            ret.setData(res.getData());
        ret.setErrno(res.getCode().getCode());
        ret.setErrmsg(res.getErrmsg());
        return ret;
    }

    @ApiOperation(value = "买家查询自己的订单（概要）")
    @Audit
    @GetMapping("orders")
    public Object searchMyselfOrders(@LoginUser Long loginUserId,
                                     @LoginName String loginName,
                                     @RequestParam(name = "orderSn", required = false) String orderSn,
                                     @RequestParam(value = "beginTime", required = false) @DateTimeFormat(pattern = "uuuu-MM-dd'T'HH:mm:ss.SSSXXX") ZonedDateTime beginTime,
                                     @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "uuuu-MM-dd'T'HH:mm:ss.SSSXXX") ZonedDateTime endTime,
                                     @RequestParam(name = "state", required = false) Integer state,
                                     @RequestParam(name = "page", required = false) Integer page,
                                     @RequestParam(name = "pageSize", required = false) Integer pageSize) {
        if (beginTime != null && endTime != null && beginTime.isAfter(endTime)) {
            ReturnObject returnObjectNotValid = new ReturnObject(ReturnNo.LATE_BEGINTIME);
            return decorateReturnObject(returnObjectNotValid);
        }
        ReturnObject res = orderService.searchMyselfOrders(loginUserId, orderSn, beginTime, endTime, state, page, pageSize);
        return decorateReturnObject(res);
    }


    @ApiOperation(value = "买家申请建立订单")
    @Audit
    @PostMapping("orders")
    public Object createMyselfOrder(@RequestBody @Validated NewOrderVo vo, @LoginUser Long loginUserId, @LoginName String loginName, BindingResult bindingResult) {

        Object returnObject = processFieldErrors(bindingResult, httpServletResponse);
        if (null != returnObject) {
            return returnObject;
        }


        ReturnObject res = orderService.createMyselfOrder(vo, loginUserId, loginName);
        if (res.getCode() != ReturnNo.OK) {
            return decorateReturnObject(res);
        }
        httpServletResponse.setStatus(HttpServletResponse.SC_CREATED);
        return decorateReturnObject(res);
    }


    @ApiOperation(value = "买家查询自己订单详细信息")
    @Audit
    @GetMapping("orders/{id}")
    public Object getMyselfOrderDetail(@LoginUser Long loginUserId, @PathVariable Long id,
                                       @LoginName String loginName) {

        ReturnObject res = orderService.getMyselfOrderDetail(loginUserId, id);
        return decorateReturnObject(res);
    }


    /**
     * @param id
     * @return
     * @author wang xusheng
     */
    @ApiOperation(value = "买家修改自己的订单")
    @ApiResponses({
            @ApiResponse(code = 0, message = "成功"),
            @ApiResponse(code = 507, message = "当前状态禁止此操作"),
    })
    @Audit
    @PutMapping("orders/{id}")
    public Object modifyMyselfOrder(@PathVariable Long id, @Validated @RequestBody OrderModifyVo orderModifyVo, @LoginUser Long loginUserId, @LoginName String loginUserName, BindingResult bindingResult) {
        Object returnObject = processFieldErrors(bindingResult, httpServletResponse);
        if (null != returnObject) {
            return returnObject;
        }
        Order orderBo = cloneVo(orderModifyVo, Order.class);
        ReturnObject res = orderService.modifyMyselfOrder(id, orderBo, loginUserId, loginUserName);
        return decorateReturnObject(res);
    }

    /**
     * @param shopId
     * @param id
     * @return
     * @creator wang xusheng
     * @author wang xusheng
     */
    @ApiOperation(value = "店家对订单标记发货")
    @Audit(departName = "shops")
    @PutMapping("shops/{shopId}/orders/{id}/deliver")
    public Object deliverOrder(@PathVariable Long shopId, @PathVariable Long id, @LoginUser Long loginUserId, @RequestBody ShipmentVo shipmentVo, @LoginName String loginName) {

        ReturnObject res = orderService.deliverOrder(loginUserId, shopId, id, shipmentVo.getShipmentSn(), loginName);
        return decorateReturnObject(res);
    }


    /**
     * @param id
     * @return
     * @creator wang xusheng
     */
    @ApiOperation(value = "查询自己订单的支付信息")
    @GetMapping("orders/{id}/payment")
    @Audit
    public Object getOrderPayInfo(@PathVariable Long id,@LoginUser Long userId) {

        ReturnObject res = orderService.getOrderPayInfo(id,userId);
        return decorateReturnObject(res);
    }


    /**
     * @author YuJie
     * @date 2021-12-14
     */
    @ApiOperation(value = "查询自己订单的退款信息")
    @GetMapping("orders/{id}/refund")
    @Audit
    public Object getOrderRefundInfo(@PathVariable Long id,@LoginUser Long userId) {

        ReturnObject res = orderService.getOrderRefundInfo(id,userId);
        return decorateReturnObject(res);
    }



    @ApiOperation(value = "买家逻辑删除本人名下订单")
    @DeleteMapping("orders/{id}")
    @Audit
    public Object deleteUserSelfOrder(@PathVariable Long id, @LoginUser Long userId, @LoginName String userName) {
        //从token获得id 传入service检验
        ReturnObject res = orderService.deleteUserSelfOrder(userId, userName, id);
        return decorateReturnObject(res);
    }

    @ApiOperation(value = "买家取消本人名下订单")
    @PutMapping("orders/{id}/cancel")
    @Audit
    public Object cancelUserSelfOrder(@PathVariable Long id, @LoginUser Long userId, @LoginName String userName) {
        ReturnObject res = orderService.cancelUserSelfOrder(id, userId, userName);
        return decorateReturnObject(res);
    }

    /**
     * @param id
     * @param userId
     * @return
     * @author wang xusheng
     */
    @ApiOperation(value = "买家标记确认收货")
    @PutMapping("orders/{id}/confirm")
    @Audit
    public Object confirmUserSelfOrder(@PathVariable Long id, @LoginUser Long userId, @LoginName String loginName) {
        ReturnObject res = orderService.confirmUserSelfOrder(userId, id, loginName);
        return decorateReturnObject(res);
    }

    @ApiOperation(value = "店家查询商户所有订单 (概要)")
    @GetMapping("shops/{shopId}/orders")
    @Audit(departName = "shops")
    public Object getShopOrder(@PathVariable Long shopId,
                               @RequestParam(name = "customerId", required = false) Long customerId,
                               @RequestParam(name = "orderSn", required = false) String orderSn,
                               @RequestParam(value = "beginTime", required = false) @DateTimeFormat(pattern = "uuuu-MM-dd'T'HH:mm:ss.SSSXXX") ZonedDateTime beginTime,
                               @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "uuuu-MM-dd'T'HH:mm:ss.SSSXXX") ZonedDateTime endTime,
                               @RequestParam(name = "page", required = false, defaultValue = "1") Integer page,
                               @RequestParam(name = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
        if (beginTime != null && endTime != null && beginTime.isAfter(endTime)) {
            ReturnObject returnObjectNotValid = new ReturnObject(ReturnNo.LATE_BEGINTIME);
            return decorateReturnObject(returnObjectNotValid);
        }
        ReturnObject res = orderService.getShopOrder(shopId, customerId, orderSn, beginTime, endTime, page, pageSize);
        return decorateReturnObject(res);
    }

    /**
     * @param shopId
     * @param id
     * @return
     * @author wang xusheng
     */
    @ApiOperation(value = "店家修改订单 (留言)")
    @PutMapping("shops/{shopId}/orders/{id}")
    @Audit(departName = "shops")
    public Object shopsModifyOrder(@PathVariable Long shopId, @PathVariable Long id, @RequestParam(required = false) String message, @LoginUser Long loginUserId, @LoginName String loginName) {

        ReturnObject res = orderService.shopsModifyOrder(loginUserId, shopId, id, message, loginName);
        return decorateReturnObject(res);
    }

    @ApiOperation(value = "店家查询店内订单完整信息（普通，团购，预售）")
    @GetMapping("shops/{shopId}/orders/{id}")
    @Audit(departName = "shops")
    public Object getShopOrderDetail(@PathVariable Long shopId, @PathVariable Long id) {

        ReturnObject res = orderService.getShopOrderDetail(shopId, id);
        return decorateReturnObject(res);
    }

    /**
     * @param shopId
     * @param id
     * @return
     * @creator wang xusheng
     */
    @ApiOperation(value = "确认团购订单")
    @PutMapping("internal/shops/{shopId}/grouponorders/{id}/confirm")
    @Audit
    public InternalReturnObject confirmGroupOnOrder(@PathVariable Long shopId, @PathVariable Long id, @LoginUser Long userId, @LoginName String userName) {

        ReturnObject res = orderService.confirmGroupOnOrder(userId, userName, shopId, id);

        InternalReturnObject ret = new InternalReturnObject();
        if(res.getData()!=null)
            ret.setData(res.getData());
        ret.setErrno(res.getCode().getCode());
        ret.setErrmsg(res.getErrmsg());
        return ret;
    }


    /**
     * @param shopId
     * @param id
     * @return
     * @creator liuyunlong
     */
    @Audit
    @ApiOperation(value = "内部API-取消订单")
    @PutMapping("internal/shops/{shopId}/orders/{id}/cancel")
    public InternalReturnObject cancelOrder(@PathVariable Long shopId, @PathVariable Long id, @LoginUser Long userId, @LoginName String userName) {

        ReturnObject res = orderService.cancelOrder(shopId, id, userId, userName);

        InternalReturnObject ret = new InternalReturnObject();
        if(res.getData()!=null)
            ret.setData(res.getData());
        ret.setErrno(res.getCode().getCode());
        ret.setErrmsg(res.getErrmsg());
        return ret;
    }


    /**
     * @param shopId
     * @return
     * @creator wang xusheng
     */
    @Audit(departName = "shops")
    @ApiOperation(value = "内部API-管理员建立售后订单")
    @PostMapping("internal/shops/{shopId}/orders")
    public InternalReturnObject creatAfterSaleOrder(@PathVariable Long shopId, @Validated @RequestBody NewAfterSaleOrderVo newAfterSaleOrderVo, @LoginUser Long loginUserId, @LoginName String loginName, BindingResult bindingResult) {

        if(shopId!=0)
            return new InternalReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE.getCode(),ReturnNo.RESOURCE_ID_OUTSCOPE.getMessage());

        Object returnObject = processFieldErrors(bindingResult, httpServletResponse);
        if (null != returnObject) {
            return new InternalReturnObject(ReturnNo.FIELD_NOTVALID.getCode(),ReturnNo.FIELD_NOTVALID.getMessage());
        }

        ReturnObject res = orderService.createAfterSaleOrder(newAfterSaleOrderVo, loginUserId, loginName);

        InternalReturnObject ret = new InternalReturnObject();
        if(res.getData()!=null)
            ret.setData(res.getData());
        ret.setErrno(res.getCode().getCode());
        ret.setErrmsg(res.getErrmsg());
        if(res.getCode()!=ReturnNo.OK){
            return ret;
        }
        httpServletResponse.setStatus(HttpServletResponse.SC_CREATED);
        return ret;
    }

    /**
     * 内部API，根据id获得orderItem
     * @param id
     * @return
     */

    @GetMapping("/internal/orderitems/{id}")
    public InternalReturnObject getOrderItemInfoById(@PathVariable("id") Long id){
        ReturnObject res=orderService.getOrderItemById(id);

        InternalReturnObject ret = new InternalReturnObject();
        if(res.getData()!=null)
            ret.setData(res.getData());
        ret.setErrno(res.getCode().getCode());
        ret.setErrmsg(res.getErrmsg());
        return ret;
    }

    /**
     * 用orderSn查询Order
     * @param orderSn
     * @return
     */
    @GetMapping("/internal/orders")
    public InternalReturnObject getOrderBySn(@RequestParam("orderSn") String orderSn){
        ReturnObject res = orderService.getOrderDetailByOrderSn(orderSn);

        InternalReturnObject ret = new InternalReturnObject();
        if(res.getData()!=null)
            ret.setData(res.getData());
        ret.setErrno(res.getCode().getCode());
        ret.setErrmsg(res.getErrmsg());
        return ret;
    }




}
